package com.spzx.channel.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.spzx.channel.domain.vo.IndexVO;
import com.spzx.channel.service.IndexService;
import com.spzx.common.core.domain.R;
import com.spzx.common.core.exception.ServiceException;
import com.spzx.common.core.utils.StringUtils;
import com.spzx.product.api.RemoteBrandService;
import com.spzx.product.api.RemoteCategoryService;
import com.spzx.product.api.RemoteProductService;
import com.spzx.product.api.domain.Brand;
import com.spzx.product.api.domain.Category;
import com.spzx.product.api.domain.ProductSku;
import com.spzx.product.api.domain.query.ProductSkuQuery;
import com.spzx.product.api.domain.vo.ProductSkuVO;
import jakarta.annotation.Resource;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.List;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

@Service
public class IndexServiceImpl implements IndexService {

    @Resource
    RemoteProductService remoteProductService;
    @Resource
    RemoteCategoryService remoteCategoryService;

    @Resource
    RemoteBrandService remoteBrandService;
    @Resource
    StringRedisTemplate stringRedisTemplate;

    @Override
    public IndexVO getIndexPageData() {
        //1、远程调用product服务 获取首页需要的一级分类集合  根据pid=0查询一级分类
        R<List<ProductSku>> listProductSkuR = remoteProductService.listIndexSkus();
        if (listProductSkuR.getCode() != 200) {
            throw new ServiceException("获取热门数据失败");
        }


        //2、远程调用product服务 获取首页需要的热门数据集合  查询sku表 销量最高的8条记录
        R<List<Category>> listIndexCatesR = remoteCategoryService.listIndexCates();
        if (listIndexCatesR.getCode() != 200) {
            throw new ServiceException("获取分类数据失败");

        }
        //3、组装首页需要的数据返回
        IndexVO indexVO = new IndexVO();
        //首页需要的分类数据 和 sku数据 都需要哪些属性值
        indexVO.setCategoryList(listIndexCatesR.getData());
        indexVO.setProductSkuList(listProductSkuR.getData());
        return indexVO;


    }

    @Override
    public Page<ProductSku> getSkuList(ProductSkuQuery query) {


        R<Page<ProductSku>> pageR = remoteProductService.listSkus(query);
        if (pageR.getCode() != 200) {
            return null;

        }
        return pageR.getData();
    }

    @Override
    public List<Brand> getBrandAll() {
        R<List<Brand>> listR = remoteBrandService.listAllBrands();

        return listR.getData();
    }


//    @Cacheable(value = "spzx:cache:channel:sku",key = "#skuId")

    @Override
    public ProductSkuVO getSkuById(Long skuId) {

        R<ProductSkuVO> skuDetails = remoteProductService.getSkuDetails(skuId);

        return skuDetails.getData();


    }
    @Override

    // v3 看门狗 自动续期过期时间
    public synchronized void testCache() {
        // 2 设置定期时间

        Boolean flag = stringRedisTemplate.opsForValue().setIfAbsent("channel:lock:test", "1",
                3,TimeUnit.SECONDS);

        if (flag){

            renewExpire("channel:lock:test",5);

            Boolean hasKey = stringRedisTemplate.hasKey("lock:number");
            if (!hasKey) {
                //如果number 不存在 实例化它写入Redis中
                stringRedisTemplate.opsForValue().set("lock:number", "1", 1, TimeUnit.HOURS);

            } else {
                // 如果存在 在之前的基础上加1
                String s = stringRedisTemplate.opsForValue().get("lock:number");
                stringRedisTemplate.opsForValue().set("lock:number", Integer.parseInt(s) + 1 + "", 1, TimeUnit.HOURS);


            }
//            stringRedisTemplate.delete("channel:lock:test");

        }else {

            try {
                TimeUnit.MICROSECONDS.sleep(50);
                testCache();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

        }


    }
// 自动续期
    ScheduledExecutorService executor=Executors.newScheduledThreadPool(3);

    public static void main(String[] args) {
        ScheduledExecutorService executor1=Executors.newScheduledThreadPool(3);
        executor1.scheduleAtFixedRate(()->{
            System.out.println("自动续期"+new Date());

        },20/3,20/3,TimeUnit.SECONDS);



    }
    private void renewExpire(String key, int expire) {

    }


//    @Override
//
//   // v1
//    public synchronized void testCache() {
//        // 2 设置定期时间
//
//        Boolean flag = stringRedisTemplate.opsForValue().setIfAbsent("channel:lock:test", "1",
//                3,TimeUnit.SECONDS);
//
//        if (flag){
//
//            Boolean hasKey = stringRedisTemplate.hasKey("lock:number");
//            if (!hasKey) {
//                //如果number 不存在 实例化它写入Redis中
//                stringRedisTemplate.opsForValue().set("lock:number", "1", 1, TimeUnit.HOURS);
//
//            } else {
//                // 如果存在 在之前的基础上加1
//                String s = stringRedisTemplate.opsForValue().get("lock:number");
//                stringRedisTemplate.opsForValue().set("lock:number", Integer.parseInt(s) + 1 + "", 1, TimeUnit.HOURS);
//
//
//            }
////            stringRedisTemplate.delete("channel:lock:test");
//
//        }else {
//
//            try {
//                TimeUnit.MICROSECONDS.sleep(50);
//                testCache();
//            } catch (InterruptedException e) {
//                throw new RuntimeException(e);
//            }
//
//        }
//
//
//    }





//    @Override

//    public synchronized void testCache() {
//
//
//
//        Boolean hasKey = stringRedisTemplate.hasKey("lock:number");
//        if (!hasKey) {
//            //如果number 不存在 实例化它写入Redis中
//            stringRedisTemplate.opsForValue().set("lock:number", "1", 1, TimeUnit.HOURS);
//
//        } else {
//            // 如果存在 在之前的基础上加1
//            String s = stringRedisTemplate.opsForValue().get("lock:number");
//            stringRedisTemplate.opsForValue().set("lock:number", Integer.parseInt(s) + 1 + "", 1, TimeUnit.HOURS);
//
//
//        }
//    }


}

